home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- **** ****
- **** ocrtrain.cpp ****
- **** ****
- **** atree release 2.7 for Windows ****
- **** Adaptive Logic Network (ALN) simulation program. ****
- **** Copyright (C) M. Thomas, N. Sanche, W.W. Armstrong 1991, 1992 ****
- **** ****
- **** License: ****
- **** A royalty-free license is granted for the use of this software for ****
- **** NON_COMMERCIAL PURPOSES ONLY. The software may be copied and/or ****
- **** modified provided this notice appears in its entirety and unchanged ****
- **** in all derived source programs. Persons modifying the code are ****
- **** requested to state the date, the changes made and who made them ****
- **** in the modification history. ****
- **** ****
- **** Patent License: ****
- **** The use of a digital circuit which transmits a signal indicating ****
- **** heuristic responsibility is protected by U. S. Patent 3,934,231 ****
- **** and others assigned to Dendronic Decisions Limited of Edmonton, ****
- **** W. W. Armstrong, President. A royalty-free license is granted ****
- **** by the company to use this patent for NON_COMMERCIAL PURPOSES to ****
- **** adapt logic trees using this program and its modifications. ****
- **** ****
- **** Limited Warranty: ****
- **** This software is provided "as is" without warranty of any kind, ****
- **** either expressed or implied, including, but not limited to, the ****
- **** implied warrantees of merchantability and fitness for a particular ****
- **** purpose. The entire risk as to the quality and performance of the ****
- **** program is with the user. Neither the authors, nor the ****
- **** University of Alberta, its officers, agents, servants or employees ****
- **** shall be liable or responsible in any way for any damage to ****
- **** property or direct personal or consequential injury of any nature ****
- **** whatsoever that may be suffered or sustained by any licensee, user ****
- **** or any other party as a consequence of the use or disposition of ****
- **** this software. ****
- **** Modification history: ****
- **** ****
- **** 92.04.27 atree v2.5 for Windows, M. Thomas ****
- **** 92.03.07 Release 2.6, Monroe Thomas, Neal Sanche ****
- **** 92.01.08 Release 2.7, Monroe Thomas, Neal Sanche ****
- **** ****
- *****************************************************************************/
-
- // ocrtrain.cpp
-
- #include "ocr.h"
- #include <edit.h>
-
- void
- TOcr::translate(HBITMAP hbm1, int dx, int dy)
- {
- HBITMAP hbm2;
- BITMAP bm;
- HDC hdc1 = CreateCompatibleDC(NULL);
- HDC hdc2 = CreateCompatibleDC(NULL);
- GetObject(hbm1, sizeof(BITMAP), (LPSTR)&bm);
-
- hbm2 = CreateBitmap(bm.bmWidth * 2, bm.bmHeight * 2, bm.bmPlanes,
- bm.bmBitsPixel, NULL);
-
- SelectObject(hdc1, hbm1);
- SelectObject(hdc2, hbm2);
-
- SetStretchBltMode(hdc1, COLORONCOLOR);
- SetStretchBltMode(hdc2, WHITEONBLACK);
-
- StretchBlt(hdc2, 0 + dx, 0 + dy,
- bm.bmWidth * 2,
- bm.bmHeight * 2,
- hdc1, 0, 0,
- bm.bmWidth,
- bm.bmHeight,
- SRCCOPY);
- StretchBlt(hdc1, 0, 0,
- bm.bmWidth,
- bm.bmHeight,
- hdc2, 0, 0,
- bm.bmWidth * 2,
- bm.bmHeight * 2,
- SRCCOPY);
-
- DeleteDC(hdc1);
- DeleteDC(hdc2);
- DeleteObject(hbm2);
- }
-
- #define NOISEBITS (16*30)
-
- void
- TOcr::train(TrainStruct& ts)
- {
- PTDialog TrainSet;
- PTBStatic TrainPct;
- LPBIT_VEC training_set;
- LPBIT_VEC desired;
- char des[1];
- WORD numsamples = ts.numsamples * 5;
- float numdone = 0;
- char szBuffer[8];
- PTBitmap A[27];
- PTBitmap L[27];
- PTBitmap N[27];
-
- WORD width = LetterBitmap->GetBytes(); //in bytes
- WORD length = width * 8;
- WORD numbits = .95 * length;
-
- if (LetterBitmap->GetPlanes() != 1)
- {
- BWCCMessageBox(HWindow, "Need monochrome bitmaps!", "OCR Train", MB_OK);
- exit(0);
- }
-
- TrainSet = new TDialog(this, OCR_TRAINSET);
- TrainPct = new TBStatic(TrainSet, OCR_TRAINPCT, 8);
- GetApplication()->MakeWindow(TrainSet);
-
- UpdateWindow(HWindow);
-
- HCURSOR hcursor = LoadCursor(NULL, IDC_WAIT);
- hcursor = SetCursor(hcursor);
-
- for (WORD i = 0; i < 3; i++)
- {
- A[i] = new TBitmap(ts.bitmaps[0]);
- L[i] = new TBitmap(ts.bitmaps[1]);
- N[i] = new TBitmap(ts.bitmaps[2]);
- }
-
- A[1]->Rotate(ts.maxrotation);
- L[1]->Rotate(ts.maxrotation);
- N[1]->Rotate(ts.maxrotation);
-
- A[2]->Rotate(-ts.maxrotation);
- L[2]->Rotate(-ts.maxrotation);
- N[2]->Rotate(-ts.maxrotation);
-
- for (i = 3; i < 27; i++)
- {
- A[i] = new TBitmap(A[i % 3]->GetBitmap());
- L[i] = new TBitmap(L[i % 3]->GetBitmap());
- N[i] = new TBitmap(N[i % 3]->GetBitmap());
- }
-
- for (i = 3; i < 24; i++)
- {
- int dx, dy;
- if (i < 6)
- {
- dx = 0; dy = 1;
- }
- if (i < 9)
- {
- dx = 1; dy = 0;
- }
- if (i < 12)
- {
- dx = 1; dy = 1;
- }
- if (i < 15)
- {
- dx = 0; dy = -1;
- }
- if (i < 18)
- {
- dx = -1; dy = 0;
- }
- if (i < 21)
- {
- dx = -1; dy = -1;
- }
- if (i < 24)
- {
- dx = -1; dy = 1;
- }
- if (i < 27)
- {
- dx = 1; dy = -1;
- }
- translate(A[i]->GetBitmap(), dx, dy);
- translate(L[i]->GetBitmap(), dx, dy);
- translate(N[i]->GetBitmap(), dx, dy);
- }
-
- training_set = (LPBIT_VEC)farmalloc(sizeof(bit_vec) * numsamples);
- MEMCHECK(training_set);
-
- desired = (LPBIT_VEC)farmalloc(sizeof(bit_vec) * numsamples);
- MEMCHECK(desired);
-
- for (i = 0; i < numsamples; i++)
- {
- training_set[i].len = length;
- training_set[i].bv = (LPSTR)farmalloc(width);
- desired[i].bv = NULL;
- }
-
- SetCursor(hcursor);
-
- UpdateWindow(HWindow);
-
- // Grab a good A
- A[0]->GetBits(training_set[0].bv);
- des[0] = 1; // want 1 output
- desired[0] = *(bv_pack(des,1));
-
- // Grab a good L
- L[0]->GetBits(training_set[1].bv);
- des[0] = 0; // want 0 output
- desired[1] = *(bv_pack(des,1));
-
- // Grab a good N
- N[0]->GetBits(training_set[2].bv);
- des[0] = 0; // want 0 output
- desired[2] = *(bv_pack(des,1));
-
- numdone += 3;
-
- // create training data
- for (i = 1; i < ts.numsamples; i++)
- {
- /* allow multitasking during long loop! */
- Windows_Interrupt(100);
-
- if (shutdown || stop) break;
-
- // Get an A
- A[random(27)]->GetBits(training_set[i*3].bv);
- des[0] = 1; // want 1 output
- desired[i*3] = *(bv_pack(des,1));
-
- for (WORD j = 0; j < numbits; j++)
- {
- bv_set(RANDOM(length), &(training_set[i*3]), RANDOM(2));
- }
-
- if (shutdown || stop) break;
-
- // Get a L
- L[random(27)]->GetBits(training_set[i*3 + 1].bv);
- des[0] = 0; // want 0 output
- desired[(i*3) + 1] = *(bv_pack(des,1));
-
- for (j = 0; j < numbits; j++)
- {
- bv_set(RANDOM(length), &(training_set[i*3 + 1]), RANDOM(2));
- }
-
- if (shutdown || stop) break;
-
- // Get a N
- N[random(27)]->GetBits(training_set[i*3 + 2].bv);
- des[0] = 0; // want 0 output
- desired[(i*3) + 2] = *(bv_pack(des,1));
-
- for (j = 0; j < numbits; j++)
- {
- bv_set(RANDOM(length), &(training_set[i*3 + 2]), RANDOM(2));
- }
- numdone += 3;
- sprintf(szBuffer, "%% %4.2f", 100.0 * (numdone / numsamples));
- TrainPct->SetText(szBuffer);
- }
-
- // Now reinforce on a white frame
- if (!(shutdown || stop))
- {
- A[0]->GetBits(training_set[ts.numsamples * 3].bv);
- des[0] = 0;
- desired[ts.numsamples * 3] = *(bv_pack(des,1));
-
- for (WORD j = 0; j < length; j++)
- {
- bv_set(j, &(training_set[ts.numsamples * 3]), 1);
- }
- numdone++;
- }
-
- for (i = (ts.numsamples * 3) + 1; i < (ts.numsamples * 4); i++)
- {
- if (shutdown || stop) break;
-
- Windows_Interrupt(100);
-
- // Get white frame
- _fmemcpy(training_set[i].bv, training_set[ts.numsamples * 3].bv, width);
- des[0] = 0; // want 0 output
- desired[i] = *(bv_pack(des,1));
-
- for (WORD j = 0; j < numbits; j++)
- {
- bv_set(RANDOM(length), &(training_set[i]), RANDOM(2));
- }
-
- numdone ++;
- sprintf(szBuffer, "%% %4.2f", 100.0 * (numdone / numsamples));
- TrainPct->SetText(szBuffer);
- }
-
- // Now reinforce on a black frame
-
- if (!(shutdown || stop))
- {
- A[0]->GetBits(training_set[ts.numsamples * 4].bv);
- des[0] = 0;
- desired[ts.numsamples * 4] = *(bv_pack(des,1));
-
- for (WORD j = 0; j < length; j++)
- {
- bv_set(j, &(training_set[ts.numsamples * 4]), 0);
- }
- numdone++;
- }
-
- for (i = (ts.numsamples * 4) + 1; i < (ts.numsamples * 5); i++)
- {
- if (shutdown || stop) break;
-
- Windows_Interrupt(100);
-
- // Get black frame
- _fmemcpy(training_set[i].bv, training_set[ts.numsamples * 4].bv, width);
- des[0] = 0; // want 0 output
- desired[i] = *(bv_pack(des,1));
-
- for (WORD j = 0; j < numbits; j++)
- {
- bv_set(RANDOM(length), &(training_set[i]), RANDOM(2));
- }
- numdone ++;
- sprintf(szBuffer, "%% %4.2f", 100.0 * (numdone / numsamples));
- TrainPct->SetText(szBuffer);
- }
-
- TrainSet->ShutDownWindow();
-
- // Train tree
-
- for (i = 0; i < ts.voters; i++)
- {
- if (shutdown || stop) break;
-
- char szBuf[80];
- LPATREE atree;
- sprintf(szBuf,"Now training tree %d...", i + 1);
- Status->SetText(szBuf);
- EnableWindow(Stop->HWindow, FALSE);
-
- atree = atree_create(length,ts.treesize);
- int result = atree_train(atree, training_set, desired, 0, numsamples,
- ts.mincorrect / 100 * numsamples,
- ts.maxepochs, 1);
- if (result != -1)
- {
- atree_fold(atree);
- atree_write(ts.stream, atree);
- }
- else
- {
- stop = TRUE;
- }
- atree_free(atree);
- EnableWindow(Stop->HWindow, TRUE);
- }
-
- Status->SetText("ALN Demo - Light flashes on under character ALN detects");
-
- for (i = 0; i < 24; i++)
- {
- delete A[i];
- delete L[i];
- delete N[i];
- }
-
- if (shutdown) return;
-
- // if shutdown is TRUE during training, then an exit has been requested
- // we don't need to free the memory here, since Borland's memory
- // manager will do that
-
- for(WORD j = 0; j < numsamples; j++)
- {
- farfree(training_set[j].bv);
- if (desired[j].bv != NULL)
- {
- farfree(desired[j].bv);
- }
- }
-
- farfree(training_set);
- farfree(desired);
- }
-
- void
- TOcr::OcrTrain(RTMessage Msg)
- {
- EnableWindow(Start->HWindow, FALSE);
- EnableWindow(Stop->HWindow, TRUE);
- EnableWindow(Train->HWindow, FALSE);
- EnableWindow(Reverse->HWindow, FALSE);
- EnableWindow(Reset->HWindow, FALSE);
- EnableWindow(Forget->HWindow, FALSE);
- EnableWindow(EditA->HWindow, FALSE);
- EnableWindow(EditL->HWindow, FALSE);
- EnableWindow(EditN->HWindow, FALSE);
- EnableMenuItem(hSysMenu, SC_CLOSE, MF_GRAYED);
-
- Status->SetText("Retraining the ALN will take 15 - 30 minutes.");
-
- BOOL opened = FALSE;
- BOOL err = TRUE;
- char szBuf[80];
- HBITMAP tmp;
- TrainStruct ts;
- struct tagTransferBuf
- {
- char treesize[6];
- char voters[3];
- char numsamples[5];
- char maxepochs[6];
- char mincorrect[7];
- char maxrotation[5];
- } tb;
-
- _CLASSDEF(TTrainDlg)
- class TTrainDlg : public TDialog
- {
- public:
- TTrainDlg::TTrainDlg(PTWindowsObject AParent, int ResourceId,
- struct tagTransferBuf* ATransBuf)
- : TDialog(AParent, ResourceId)
- {
- new TEdit(this, ID_TREESIZE, 6);
- new TEdit(this, ID_VOTERS, 3);
- new TEdit(this, ID_NUMSAMPLES, 5);
- new TEdit(this, ID_MAXEPOCHS, 6);
- new TEdit(this, ID_MINCORRECT, 7);
- new TEdit(this, ID_MAXROTATION, 5);
- TransferBuffer = ATransBuf;
- }
- };
-
- // set default training values
- ts.treesize = 2048;
- ts.voters = 3;
- ts.numsamples = 200;
- ts.maxepochs = 30;
- ts.mincorrect = 99.9;
- ts.maxrotation = 5;
-
- shutdown = FALSE;
- stop = FALSE;
-
- while (err)
- {
- err = FALSE;
- itoa(ts.treesize, tb.treesize, 10);
- itoa(ts.voters, tb.voters, 10);
- itoa(ts.numsamples, tb.numsamples, 10);
- itoa(ts.maxepochs, tb.maxepochs, 10);
- sprintf(tb.mincorrect, "%5.2f", ts.mincorrect);
- itoa(ts.maxrotation, tb.maxrotation, 10);
-
- PTTrainDlg TrainDlg;
- TrainDlg = new TTrainDlg(this, OCR_TRAINDLG, &tb);
-
- if (GetApplication()->ExecDialog(TrainDlg) == IDCANCEL)
- {
- stop = TRUE;
- break;
- }
-
- if ((ts.treesize = atoi(tb.treesize)) == 0)
- {
- err = TRUE;
- BWCCMessageBox(HWindow, "Invalid Tree Size entry",
- NULL, MB_ICONQUESTION | MB_OK);
- }
- if ((ts.voters = atoi(tb.voters)) == 0)
- {
- err = TRUE;
- BWCCMessageBox(HWindow, "Invalid Voters entry",
- NULL, MB_ICONQUESTION | MB_OK);
- }
- if ((ts.numsamples = atoi(tb.numsamples)) == 0)
- {
- err = TRUE;
- BWCCMessageBox(HWindow, "Invalid Number of Samples entry",
- NULL, MB_ICONQUESTION | MB_OK);
- }
- if ((ts.maxepochs = atoi(tb.maxepochs)) == 0)
- {
- err = TRUE;
- BWCCMessageBox(HWindow, "Invalid Maximum Epochs entry",
- NULL, MB_ICONQUESTION | MB_OK);
- }
- if ((ts.mincorrect = atof(tb.mincorrect)) == 0)
- {
- err = TRUE;
- BWCCMessageBox(HWindow, "Invalid Minimum Percent Correct entry",
- NULL, MB_ICONQUESTION | MB_OK);
- }
- ts.maxrotation = atoi(tb.maxrotation);
- }
-
- if (!(shutdown || stop))
- {
- if ((ts.stream = fopen("ocr.tre", "w")) == NULL)
- {
- BWCCMessageBox(HWindow, "Can't open 'ocr.tre'", "OCR Train",
- MB_ICONEXCLAMATION | MB_OK);
- exit(0);
- }
-
- atree_init(GetApplication()->hInstance, HWindow);
- fprintf(ts.stream, "%d\n", ts.voters);
- opened = TRUE;
- }
-
- if (!(shutdown || stop))
- {
- ts.bitmaps[0] = LetterA->GetBitmap();
- ts.bitmaps[1] = LetterL->GetBitmap();
- ts.bitmaps[2] = LetterN->GetBitmap();
- Status->SetText("Please wait while training set is built for first character...");
- train(ts);
- }
- if (!(shutdown || stop))
- {
- tmp = ts.bitmaps[0];
- ts.bitmaps[0] = ts.bitmaps[1];
- ts.bitmaps[1] = tmp;
- Status->SetText("Please wait while training set is built for second character...");
- train(ts);
- }
- if (!(shutdown || stop))
- {
- tmp = ts.bitmaps[0];
- ts.bitmaps[0] = ts.bitmaps[2];
- ts.bitmaps[2] = tmp;
- Status->SetText("Please wait while training set is built for third character...");
- train(ts);
- }
-
- if (opened)
- {
- fclose(ts.stream);
- atree_quit();
- }
-
- if ((shutdown || stop) && opened) remove("ocr.tre");
-
- EnableWindow(Start->HWindow, TRUE);
- EnableWindow(Stop->HWindow, FALSE);
- EnableWindow(Train->HWindow, TRUE);
- EnableWindow(Reverse->HWindow, TRUE);
- EnableWindow(Reset->HWindow, TRUE);
- EnableWindow(Forget->HWindow, TRUE);
- EnableWindow(EditA->HWindow, TRUE);
- EnableWindow(EditL->HWindow, TRUE);
- EnableWindow(EditN->HWindow, TRUE);
- EnableMenuItem(hSysMenu, SC_CLOSE, MF_ENABLED);
- }
-
-
-